package com.hua.api.core.framework.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.util.IOUtils;
import com.hua.api.core.framework.http.constant.OAuthErrorEnum;
import com.hua.api.core.framework.http.constant.RequestMethodTypeEnum;
import com.hua.api.core.framework.http.exception.ApiOAuthException;
import com.hua.api.core.framework.http.exception.SgOpenException;
import com.hua.api.core.framework.http.factory.URLFactory;
import com.hua.api.core.framework.http.util.ConvertUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.StatusLine;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.List;
import java.util.Map;


@SuppressWarnings("all")
@Slf4j
public class HttpHelper {

    private static CloseableHttpClient httpClient = HttpClients.createDefault();

    public static String request(String url, Map<String, String> params,Map<String,String> headers, String requestMethodType, RequestConfig.Builder requestConfigBuilder) throws IOException, SgOpenException {

        if (RequestMethodTypeEnum.POST.getCode().equals(requestMethodType)) {
            log.info("HttpHelper.post({})",url);
            return post(url,params,headers,requestConfigBuilder);
        } else {
            url = URLFactory.genUrlForGet(url, params);
            log.info("HttpHelper.get({})",url);
            return get(url,requestConfigBuilder);
        }
    }

    private static String post(String url, Map<String, String> params,Map<String,String> headers, RequestConfig.Builder requestConfigBuilder){
        log.info("post url={}",url);
        HttpPost httpPost = new HttpPost(url);
        // add headers
        if(null!=headers){
            for(Map.Entry<String,String> en:headers.entrySet()){
                log.info("httpPost.addHeader {}={}",en.getKey(),en.getValue());
                httpPost.addHeader(en.getKey(),en.getValue());
            }
        }

        httpPost.setConfig(requestConfigBuilder.build());
        CloseableHttpResponse response = null;
        String result = null;
        try {
            List<BasicNameValuePair> nameValuePairList = ConvertUtil.convertToEntity(params);
            UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nameValuePairList, "UTF-8");
            httpPost.setEntity(uefEntity);
            response = httpClient.execute(httpPost);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode != 200) {
                if (statusCode >= 500) {
                    throw new ApiOAuthException(OAuthErrorEnum.ELSE_ERROR.getCode(), "Response :" + JSON.toJSONString(statusLine));
                }
                throw new ApiOAuthException(OAuthErrorEnum.ELSE_ERROR.getCode(), "Response :" + JSON.toJSONString(statusLine));
            }
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity, "UTF-8");
            log.info("result={}",result);
        } catch (Exception e) {

            e.printStackTrace();
        } finally {
            httpPost.releaseConnection();
            IOUtils.close(response);
        }

        return result;
    }


    public static String postJson(String url,String body,Map<String,String> headers,RequestConfig.Builder requestConfigBuilder){
        log.info("postJson={},body={}",url,body);
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(requestConfigBuilder.build());
        // httpPost.addHeader("Content-Type", "application/json");
        httpPost.setHeader("Content-Type", "application/json;charset=utf-8");
        // httpPost.addHeader("accept", "application/json");
        CloseableHttpResponse response = null;

        if(null!=headers){
            for(Map.Entry<String,String> en:headers.entrySet()){
                log.info("postJson.addHeader {}={}",en.getKey(),en.getValue());
                httpPost.addHeader(en.getKey(),en.getValue());
            }
        }

        String result = null;
        try {
            StringEntity stringEntity = new StringEntity(body,"utf-8");
            httpPost.setEntity(stringEntity);
            response = httpClient.execute(httpPost);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode != 200) {
                if (statusCode >= 500) {
                    throw new ApiOAuthException(OAuthErrorEnum.SERVER_ERROR.getMsg());
                }
                throw new ApiOAuthException(OAuthErrorEnum.ELSE_ERROR.getCode(), "Response :" + JSON.toJSONString(statusLine));
            }
            HttpEntity entity = response.getEntity();
            ContentType contentType = ContentType.getOrDefault(entity);
            result = EntityUtils.toString(entity, "utf-8");
            log.info("result={}",result);
        } catch (Exception e) {
            log.error("postJson error={}",e.getMessage());
            e.printStackTrace();
        } finally {
            httpPost.releaseConnection();
            IOUtils.close(response);
        }
        return result;
    }


    private static String get(String url, RequestConfig.Builder requestConfigBuilder) throws IOException, SgOpenException {
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(requestConfigBuilder.build());

        CloseableHttpResponse response = null;

        String var5;
        try {
            response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            var5 = EntityUtils.toString(entity, "UTF-8");
        } catch (ParseException var9) {
            throw new SgOpenException(var9);
        } finally {
            httpGet.releaseConnection();
            if (response != null) {
                response.close();
            }
        }
        log.info("response={}",var5);
        return var5;
    }


    static {
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        // poolingHttpClientConnectionManager.setMaxTotal(PropertiesUtil.getHttpClientPoolMaxTotal());
        // poolingHttpClientConnectionManager.setDefaultMaxPerRoute(PropertiesUtil.getHttpClientPoolDefaultMaxPerRoute());
        // poolingHttpClientConnectionManager.setMaxPerRoute(URLFactory.getRequestUrlRoute(), PropertiesUtil.getHttpClientPoolMaxPerRoute());
        httpClient = HttpClients.custom().setConnectionManager(poolingHttpClientConnectionManager).build();
    }


}
